{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c510b4cc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "解包后的传入的:  {'name': '小丽', 'age': 16}\n",
      "解包后的传入并且合并的:  {'name': '小丽', 'age': 18}\n",
      "merge_dict3:  {'name': '小明', 'age': 16, 'height': 180}\n"
     ]
    }
   ],
   "source": [
    "dict1 = {\"name\": \"小丽\", \"age\": 16}\n",
    "dict2 = {\"name\": \"小丽\", \"age\": 18}\n",
    "dict3 = {\"name\": \"小明\", \"height\": 180}\n",
    "merge_dict1 = {**dict1}\n",
    "print(\"解包后的传入的: \", merge_dict1)\n",
    "# 解包后，如果key有重复的，就会覆盖原来的了\n",
    "merge_dict2 = {**dict1, **dict2}\n",
    "print(\"解包后的传入并且合并的: \", merge_dict2)\n",
    "merge_dict3 = {**dict1, **dict3}\n",
    "# 把name覆盖了，age没有覆盖，增加了height\n",
    "print(\"merge_dict3: \", merge_dict3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4face0db",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "初始化的partial_variables: {'system_name': '订单系统', 'current_time': <function <lambda> at 0x7f216c0fd1b0>}\n",
      "传入的**kwargs: {'content': '订单已支付成功'}\n",
      "传入的**kwargs: {'content': '订单已发货'}\n",
      "第一次合并结果： {'system_name': '订单系统', 'current_time': '2025-11-08 12:12:02', 'content': '订单已支付成功'}\n",
      "第二次合并结果： {'system_name': '订单系统', 'current_time': '2025-11-08 12:12:02', 'content': '订单已发货'}\n"
     ]
    }
   ],
   "source": [
    "from datetime import datetime\n",
    "from typing import Any\n",
    "\n",
    "class MockPromptTemplate:\n",
    "    def __init__(self, partial_variables: dict):\n",
    "        self.partial_variables = partial_variables  # 预填充的固定变量\n",
    "        print(f\"初始化的partial_variables: {partial_variables}\")\n",
    "    \n",
    "    # 就是你提供的这个函数\n",
    "    def _merge_partial_and_user_variables(self, **kwargs: Any) -> dict[str, Any]:\n",
    "        # 处理预填充变量：如果值是函数，就执行它获取结果\n",
    "        print(f\"传入的**kwargs: {kwargs}\")\n",
    "        partial_kwargs = {\n",
    "            k: v if not callable(v) else v() for k, v in self.partial_variables.items()\n",
    "        }\n",
    "        # 合并：预填充变量 + 用户传入变量（用户变量会覆盖同名的预填充变量）\n",
    "        return {**partial_kwargs, **kwargs}\n",
    "\n",
    "\n",
    "# 1. 定义预填充变量：\n",
    "# - system_name 是固定字符串\n",
    "# - current_time 是一个函数（每次调用时生成当前时间）\n",
    "partial_vars = {\n",
    "    \"system_name\": \"订单系统\",\n",
    "    \"current_time\": lambda: datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")  # 可调用对象\n",
    "}\n",
    "\n",
    "# 2. 创建模板实例（模拟带预填充变量的场景）\n",
    "prompt = MockPromptTemplate(partial_variables=partial_vars)\n",
    "\n",
    "# 3. 用户动态传入通知内容\n",
    "user_vars1 = {\"content\": \"订单已支付成功\"}\n",
    "user_vars2 = {\"content\": \"订单已发货\"}\n",
    "\n",
    "# 4. 合并变量\n",
    "merged1 = prompt._merge_partial_and_user_variables(**user_vars1)\n",
    "merged2 = prompt._merge_partial_and_user_variables(**user_vars2)\n",
    "\n",
    "print(\"第一次合并结果：\", merged1)\n",
    "# partial_variables因为是__init__方法，仅仅会初始一次\n",
    "print(\"第二次合并结果：\", merged2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0180c7a7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': '张三', 'age': 21, 'city': '北京'}\n"
     ]
    }
   ],
   "source": [
    "# 初始字典\n",
    "input_vars = {\"name\": \"张三\", \"age\": 20}\n",
    "\n",
    "# 模拟_message.input_variables（另一个字典）\n",
    "class Message:\n",
    "    def __init__(self):\n",
    "        self.input_variables = {\"age\": 21, \"city\": \"北京\"}\n",
    "\n",
    "_message = Message()\n",
    "\n",
    "# 执行更新操作\n",
    "input_vars.update(_message.input_variables)\n",
    "\n",
    "# 查看结果\n",
    "print(input_vars)\n",
    "# 后面的把原来的替换掉了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "8852af28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "default_params {'method': 'GET', 'timeout': 30, 'headers': {'Content-Type': 'application/json'}}\n",
      "user_params {'method': 'POST', 'data': {'name': 'test'}, 'timeout': 60}\n",
      "最终请求参数： {'method': 'POST', 'timeout': 60, 'headers': {'Content-Type': 'application/json'}, 'data': {'name': 'test'}}\n"
     ]
    }
   ],
   "source": [
    "# 定义默认参数（基础配置）\n",
    "default_params = {\n",
    "    \"method\": \"GET\",\n",
    "    \"timeout\": 30,\n",
    "    \"headers\": {\"Content-Type\": \"application/json\"}\n",
    "}\n",
    "print(\"default_params\", default_params)\n",
    "# 用户传入的参数（需要覆盖默认值的部分）\n",
    "user_params = {\n",
    "    \"method\": \"POST\",  # 覆盖默认的 GET\n",
    "    \"data\": {\"name\": \"test\"},  # 新增参数\n",
    "    \"timeout\": 60  # 覆盖默认的 30\n",
    "}\n",
    "print(\"user_params\", user_params)\n",
    "# 用用户参数更新默认参数\n",
    "default_params.update(user_params)\n",
    "\n",
    "print(\"最终请求参数：\", default_params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ca564a39",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'input_variables': ['age', 'name'], 'optional_variables': ['b', 'a'], 'partial_variables': {'x': 100}, 'extra_param': '这是额外参数'}\n"
     ]
    }
   ],
   "source": [
    "# 假设外部传入的原始kwargs（可能包含额外参数或需要覆盖的参数）\n",
    "external_kwargs = {\n",
    "    \"optional_variables\": [\"b\", \"a\"],  # 与默认键冲突，会覆盖\n",
    "    \"extra_param\": \"这是额外参数\",      # 新增参数\n",
    "    \"partial_variables\": {\"x\": 100}    # 与默认键冲突，会覆盖\n",
    "}\n",
    "\n",
    "# 假设函数内部的默认变量\n",
    "input_vars = {\"name\", \"age\"}  # 集合，排序后会变成列表\n",
    "optional_variables = {\"city\"}\n",
    "partial_vars = {\"gender\": \"未知\"}\n",
    "\n",
    "# 构建最终的kwargs\n",
    "kwargs = {\n",
    "    \"input_variables\": sorted(input_vars),  # 对input_vars排序：[\"age\", \"name\"]\n",
    "    \"optional_variables\": sorted(optional_variables),  # 排序后：[\"city\"]\n",
    "    \"partial_variables\": partial_vars,  # 默认值：{\"gender\": \"未知\"}\n",
    "    **external_kwargs,  # 合并外部传入的kwargs，冲突键会覆盖前面的定义\n",
    "}\n",
    "\n",
    "# 打印结果\n",
    "print(kwargs)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain-course (3.10.12)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
